import store from "@/store";
import {Message, Modal, LoadingBar, Spin} from "view-design";
import PnUtil from "@/utils/PnUtil";
import _ from "lodash";
import PnApi from "@/api/PnApi";
import EventBus from '@/utils/EventBus'

const buildInitPageMetadata = function () {
  let pageMetadata = {
    layout: {
      layoutGroup: [

      ],
      layoutItems: [

      ]
    }
  };
  return pageMetadata
};

/**
 * 构建 绝对布局默认配置
 * @returns
 */
const buildAbsoluteLayoutConfigData = function () {
  let layoutConfigData = { // 绝对布局默认配置
    width: 1920,
    widthPixelUnit: 'px',
    height: 1080,
    heightPixelUnit: 'px',
    backgroundColor: '#0E2B43',
    syncSetPageBgColor: true, // 是否同步设置页面背景色
    dragPixel: 1,  // 拖拽单位像素

    imageRelativePath: '',
    imageRepeat: 'no-repeat',
    imageSize: '100% 100%',

    styleFilter_use: false,
    styleFilter_hueRotate: 0,
    styleFilter_contrast: 100,
    styleFilter_opacity: 100,
    styleFilter_saturate: 100,
    styleFilter_brightness: 100,

    customStyleCode: '{\n}',

    pageScalingMode: 'w-constrain', // 页面缩放模式，none：不缩放，w-constrain：宽度等比例缩放，h-constrain：高度等比例缩放，w-h-constrain：全屏铺满

    pageGlobalStyleCode: '',  // 页面全局样式
    designPhaseNotLoadGlobalStyle: false, // 设计阶段不加载页面全局样式
    pageGlobalJsCode: 'if(!PnUtil.isDesignerPage()){\n  //此处编辑脚本主体\n  \n}',     // 页面全局JS脚本

    hideHttpLoadingBar: true, // 页面发布后是否显示数据请求时的进度条
  };
  return layoutConfigData
};

/**
 * 构建 绝对布局布局块对象
 * @param payload
 * @returns
 */
const buildAbsoluteLayoutItem = function () {
  let layoutItem = {
    id: PnUtil.uuid(),
    name: 'DefaultLayoutItem',
    aliasName: '',
    layoutItemConfigData: {
      className: '',

      draggableEnabled: true,
      resizableEnabled: true,

      width: 250,
      height: 250,
      left: 0,
      top: 0,

      backgroundColor: '',
      padding: 0,

      backgroundColorHover: '', // 鼠标滑入背景色（弃用）
      mouseenterScript: '', // 鼠标滑入事件脚本（弃用）
      mouseleaveScript: '', // 鼠标滑出事件脚本（弃用）

      borderWidth: 0,
      borderStyle: 'solid',
      borderColor: '#000',

      borderTopLeftRadius: 0,
      borderTopRightRadius: 0,
      borderBottomLeftRadius: 0,
      borderBottomRightRadius: 0,

      boxShadowInset: false,
      boxShadowLeft: 0,
      boxShadowTop: 0,
      boxShadowRadius: 0,
      boxShadowColor: '',

      zIndex: 2,

      mouseEventPierce: false, // 鼠标事件穿透

      animationVisible: false,
      animationDelay: '',
      inAnimation: '',
      outAnimation: '',

      rotationAngle: 0, // 旋转角度
      flipHorizontal: false, // 水平翻转
      flipVertical: false, // 垂直翻转

      use3dRotate: false, // 是否启用3D旋转
      axisOfRotation: 'y', // 旋转轴
      rotationAngleFor3d: 30, // 旋转角度
      perspectiveFor3d: 500, // 透视距离

      opacity: 1,
      display: 'block',

      customStyleCode: '{\n}',

    },
    component: {
      id: '',
      name: '',
      compConfigData: {

      }
    }
  };

  return layoutItem
};

/**
 * 构建 绝对布局组项对象
 */
const buildAbsoluteGroupItem = function () {
  let groupItem = {
    id: PnUtil.uuid(),
    name: '',
    groupItemConfigData: {
      draggable: true,

      animationVisible: false,
      animationDelay: '',
      inAnimation: '',
      outAnimation: '',

      width: 0,
      height: 0,
      left: 0,
      top: 0,

      display: 'block'
    },
    layoutItemIds: []
  };
  return groupItem
};

/********************************组相关操作函数********************************/

/**
 * 计算组项尺寸与定位坐标
 * @param layoutItemIds
 * @returns {{top: number, left: number, width: number, height: number}}
 */
const calculateGroupItemSizeAndLocation = function (layoutItemIds) {
  let layoutItems = [];
  layoutItemIds.forEach(id => {
    layoutItems.push(store.getters['designer/getLayoutItemById'](id))
  });

  let size = {
    width: 0,
    height: 0,
    left: 0,
    top: 0
  };

  if (layoutItems.length > 0) {

    let leftTopCoords = []; // 所有布局块左上坐标集合
    let rightBottomCoords = []; // 所有布局块右下坐标集合

    let widths = []; // 左右布局块的宽度集合
    let heights = []; // 左右布局块的高度集合

    layoutItems.forEach(layoutItem => {
      let leftTopCoord = {
        left: layoutItem.layoutItemConfigData.left,
        top: layoutItem.layoutItemConfigData.top,
      };
      let rightBottomCoord = {
        left: layoutItem.layoutItemConfigData.left + layoutItem.layoutItemConfigData.width,
        top: layoutItem.layoutItemConfigData.top + layoutItem.layoutItemConfigData.height
      };
      leftTopCoords.push(leftTopCoord);
      rightBottomCoords.push(rightBottomCoord);

      widths.push(layoutItem.layoutItemConfigData.width);
      heights.push(layoutItem.layoutItemConfigData.height);
    });

    // 最左坐标
    let farLeftCoord = leftTopCoords.reduce((obj1, obj2) => {
      return obj1.left < obj2.left ? obj1 : obj2
    });

    // 最右坐标
    let farRightCoord = rightBottomCoords.reduce((obj1, obj2) => {
      return obj1.left > obj2.left ? obj1 : obj2
    });

    // 最上坐标
    let farTopCoord = leftTopCoords.reduce((obj1, obj2) => {
      return obj1.top < obj2.top ? obj1 : obj2
    });

    // 最下坐标
    let farBottomCoord = rightBottomCoords.reduce((obj1, obj2) => {
      return obj1.top > obj2.top ? obj1 : obj2
    });

    let maxWidth = widths.reduce((obj1, obj2) => {
      return obj1 > obj2 ? obj1 : obj2
    });

    let maxHeight = heights.reduce((obj1, obj2) => {
      return obj1 > obj2 ? obj1 : obj2
    });

    size.width = farRightCoord.left - farLeftCoord.left;
    size.height = farBottomCoord.top - farTopCoord.top;
    size.left = farLeftCoord.left;
    size.top = farTopCoord.top;

    if (size.width < maxWidth) {
      size.width = maxWidth
    }
    if (size.height < maxHeight) {
      size.height = maxHeight
    }

  }

  return size;
};

/**
 * 更新指定组项的尺寸位置
 * @param groupItemId
 */
const updateGroupItemStoreSize = function (groupItemId) {
  if (groupItemId) {
    let groupItem = store.getters['designer/getLayoutGroupItemById'](groupItemId);
    let size = calculateGroupItemSizeAndLocation(groupItem.layoutItemIds);
    store.commit('designer/setGroupItemWhlt',
      {
        id: groupItemId,
        width: size.width, height: size.height, left: size.left, top: size.top
      });
  }
};

/********************************布局块与组右键菜单快捷操作封装********************************/
const groupItemSetTop = function (groupItemIds) {
  let maxZIndex = 0;
  let promise = new Promise((resolve, reject) => {
    LoadingBar.start()
    let allLayoutItem = store.getters['designer/getLayoutItems']

    for (let i=0; i<allLayoutItem.length; i++) {
      if (allLayoutItem[i].layoutItemConfigData.zIndex > maxZIndex) {
        maxZIndex = allLayoutItem[i].layoutItemConfigData.zIndex
      }
    }

    groupItemIds.forEach(id => {
      let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
      tmpGroupItem.layoutItemIds.forEach(id => {
        store.commit('designer/setLayoutItemZIndex', {id: id, zIndex: maxZIndex + 1})
      });
    });

    resolve()
  })
  promise.then(result => {
    LoadingBar.finish()
    Message.info({
      content: '成功设置选中组下布局块的层级为：' + (maxZIndex + 1)
    });
  })
};

const groupItemSetDown = function (groupItemIds) {
  let minIndex = 9999;
  let promise = new Promise((resolve, reject) => {
    LoadingBar.start()
    let allLayoutItem = store.getters['designer/getLayoutItems']

    for (let i=0; i<allLayoutItem.length; i++) {
      if (allLayoutItem[i].layoutItemConfigData.zIndex < minIndex) {
        minIndex = allLayoutItem[i].layoutItemConfigData.zIndex
      }
    }

    groupItemIds.forEach(id => {
      let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
      tmpGroupItem.layoutItemIds.forEach(id => {
        store.commit('designer/setLayoutItemZIndex', {id: id, zIndex: minIndex - 1})
      });
    });

    resolve()
  })
  promise.then(result => {
    LoadingBar.finish()
    Message.info({
      content: '成功设置选中组下布局块的层级为：' + (minIndex - 1)
    });
  })
};

const groupItemHide = function (groupItemIds) {
  groupItemIds.forEach(id => {
    store.commit('designer/setGroupItemDisplay', {id: id, display: 'none'});
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    tmpGroupItem.layoutItemIds.forEach(id => {
      store.commit('designer/setLayoutItemDisplay', {id: id, display: 'none'})
    });
  });
};

const groupItemReverseHideOrShow = function (groupItemIds, hide) {
  let selectLayoutItemIds = [];
  let layoutGroup = store.getters['designer/getLayoutGroup'];
  layoutGroup.forEach(groupItem => {
    if (groupItemIds.indexOf(groupItem.id) == -1) {
      store.commit('designer/setGroupItemDisplay', {id: groupItem.id, display: hide ? 'none':'block'});
    }else {
      groupItem.layoutItemIds.forEach(id => {
        selectLayoutItemIds.push(id)
      })
    }
  });
  let layoutItems = store.getters['designer/getLayoutItems'];
  layoutItems.forEach(layoutItem => {
    if (selectLayoutItemIds.indexOf(layoutItem.id) == -1) {
      store.commit('designer/setLayoutItemDisplay', {id: layoutItem.id, display: hide ? 'none':'block'})
    }
  })
};

const groupItemShow = function (groupItemIds) {
  groupItemIds.forEach(id => {
    store.commit('designer/setGroupItemDisplay', {id: id, display: 'block'});
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    tmpGroupItem.layoutItemIds.forEach(id => {
      store.commit('designer/setLayoutItemDisplay', {id: id, display: 'block'})
    });
  });
};

const groupItemLock = function (groupItemIds) {
  groupItemIds.forEach(id => {
    store.commit('designer/setGroupItemDraggable', {id: id, draggable: false});
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    tmpGroupItem.layoutItemIds.forEach(layoutItemId => {
      store.commit('designer/setLayoutItemDraggableEnabled', {id: layoutItemId, draggableEnabled: false})
    })
  })
};

const groupItemUnLock = function (groupItemIds) {
  groupItemIds.forEach(id => {
    store.commit('designer/setGroupItemDraggable', {id: id, draggable: true});
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    tmpGroupItem.layoutItemIds.forEach(layoutItemId => {
      store.commit('designer/setLayoutItemDraggableEnabled', {id: layoutItemId, draggableEnabled: true})
    })
  })
};

const groupItemReverseLock = function (groupItemIds) {
  groupItemIds.forEach(id => {
    store.commit('designer/setGroupItemDraggableReverse', {id: id});
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    tmpGroupItem.layoutItemIds.forEach(layoutItemId => {
      store.commit('designer/setLayoutItemDraggableEnabledReverse', {id: layoutItemId})
    })
  })
}

const groupItemUndo = function (groupItemIds) {
  Modal.confirm({
    title: '提醒',
    content: '确认取消选中组的成组状态吗？',
    onOk: () => {
      groupItemIds.forEach(id => {
        store.commit('designer/deleteGroupItem', id);
        store.commit('designer/setCurrentSelectGroupItemId', '');
      });
    }
  });
};

/**
 * @param groupItemIds 组ID数据
 * @param showConfirm 是否显示确认提示
 */
const groupItemDelete = function (groupItemIds, showConfirm = true) {
  let func = () => {
    groupItemIds.forEach(id => {
      let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
      tmpGroupItem.layoutItemIds.forEach(id => {
        store.commit('designer/deleteLayoutItem', id);
        store.commit('designer/setCurrentSelectLayoutItemId', '');
        store.commit('designer/setCurrentSelectLayoutItemIds', []);
        store.commit('designer/setRightSidebarFuncCompConfigFormName', '');
      });
      store.commit('designer/deleteGroupItem', id);
      store.commit('designer/setCurrentSelectGroupItemId', '');
    })
  }
  if (showConfirm) {
    Modal.confirm({
      title: '提醒',
      content: '确认删除选中组及组内关联的布局块吗？',
      onOk: () => {
        func()
      }
    });
  }else {
    func()
  }
};

const groupItemCopy = function (groupItemIds) {
  groupItemIds.forEach(id => {
    let tmpGroupItem = store.getters['designer/getLayoutGroupItemById'](id);
    let newUuid = PnUtil.uuid();
    let newGroupItem = PnUtil.deepClone(tmpGroupItem);
    let newLayoutItemIds = copyLayoutItems(tmpGroupItem.layoutItemIds);
    newGroupItem.id = newUuid;
    newGroupItem.layoutItemIds = newLayoutItemIds;
    store.commit('designer/addLayoutGroupItem', newGroupItem);
    store.commit('designer/setCurrentSelectGroupItemId', newUuid);
    updateGroupItemStoreSize(newUuid);
  });
}

/**
 * 复制布局块
 * @param layoutItemIds 布局块ID数组
 * @returns {Array} 返回新的布局块ID数据
 */
const copyLayoutItems = function (layoutItemIds) {
  let newLayoutItemIds = [];

  layoutItemIds.forEach(id => {
    let layoutItem = store.getters['designer/getLayoutItemById'](id);
    let newLayoutItemConfigData = PnUtil.deepClone(layoutItem.layoutItemConfigData);
    newLayoutItemConfigData.left = layoutItem.layoutItemConfigData.left + 30;
    newLayoutItemConfigData.top = layoutItem.layoutItemConfigData.top + 30;

    let newLayoutItem = {
      id: PnUtil.uuid(),
      name: layoutItem.name,
      aliasName: layoutItem.aliasName,
      layoutItemConfigData: newLayoutItemConfigData,
      component: {
        id: '',
        name: '',
        compConfigData: {}
      }
    };
    if(layoutItem.component.id) {
      let newComponent = PnUtil.deepClone(layoutItem.component);
      newComponent.id = PnUtil.uuid();
      if (newComponent.compConfigData.interaction_stream) {
        newComponent.compConfigData.interaction_stream.forEach(streamItem => {
          streamItem.interaction_sender = false;
          streamItem.interaction_fieldsMap.forEach(fm => {
            fm.bindingVariateName = ''
          })
        })
      }
      newLayoutItem.component = newComponent
    }

    store.commit('designer/addLayoutItem', newLayoutItem);
    newLayoutItemIds.pushNoRepeat(newLayoutItem.id)
  });

  return newLayoutItemIds
};

const layoutItemSetTop = function (layoutItemIds) {
  let maxZIndex = 0;
  let promise = new Promise((resolve, reject) => {
    LoadingBar.start()
    let allLayoutItem = store.getters['designer/getLayoutItems']
    for (let i=0; i<allLayoutItem.length; i++) {
      if (allLayoutItem[i].layoutItemConfigData.zIndex > maxZIndex) {
        maxZIndex = allLayoutItem[i].layoutItemConfigData.zIndex
      }
    }
    layoutItemIds.forEach(id => {
      store.commit('designer/setLayoutItemZIndex', {id: id, zIndex: maxZIndex + 1})
    });
    resolve()
  })
  promise.then((result) => {
    LoadingBar.finish()
    Message.info({
      content: '成功设置选中的布局块的层级为：' + (maxZIndex + 1)
    });
  })
};

const layoutItemSetTopOne = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemZIndex', {id: id, topOne: true})
  });
};

const layoutItemSetDown = function (layoutItemIds) {
  let minIndex = 9999
  let promise = new Promise((resolve, reject) => {
    LoadingBar.start()
    let allLayoutItem = store.getters['designer/getLayoutItems']
    for (let i=0; i<allLayoutItem.length; i++) {
      if (allLayoutItem[i].layoutItemConfigData.zIndex < minIndex) {
        minIndex = allLayoutItem[i].layoutItemConfigData.zIndex
      }
    }
    layoutItemIds.forEach(id => {
      store.commit('designer/setLayoutItemZIndex', {id: id, zIndex: minIndex - 1})
    });
    resolve()
  })
  promise.then((result) => {
    LoadingBar.finish()
    Message.info({
      content: '成功设置选中的布局块的层级为：' + (minIndex - 1)
    });
  })
  // layoutItemIds.forEach(id => {
  //   store.commit('designer/setLayoutItemZIndex', {id: id, zIndex: 1})
  // });
};

const layoutItemSetDownOne = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemZIndex', {id: id, downOne: true})
  });
};

const layoutItemHide = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemDisplay', {id: id, display: 'none'})
  });
};

/**
 * 判断布局块是否已被成组
 * @param layoutGroup
 * @param layoutItemIds
 */
const affirmLayoutItemsByGroup = function (layoutGroup, layoutItemIds) {
  let allLayoutItemIds = [];

  layoutGroup.forEach(groupItem => {
    groupItem.layoutItemIds.forEach(layoutItemId => {
      allLayoutItemIds.pushNoRepeat(layoutItemId)
    })
  });

  let flag = false;

  for (let i = 0; i < layoutItemIds.length; i++) { // 判断当前所选布局块中是否已经有被成组的对象
    for (let j = 0; j < allLayoutItemIds.length; j++) {
      if (layoutItemIds[i] === allLayoutItemIds[j]) {
        flag = true;
        break
      }
    }
  }

  return flag
}

const layoutItemCreateGroup = function (layoutGroup, layoutItemIds) {
  let flag = affirmLayoutItemsByGroup(layoutGroup, layoutItemIds)

  if (flag) {
    Message.error({
      content: '选中项中存在已被成组的布局块，请重新选择',
      duration: 5
    })
  }else {
    let groupItem = buildAbsoluteGroupItem();
    layoutItemIds.forEach(id => {
      groupItem.layoutItemIds.push(id)
    });
    let size = calculateGroupItemSizeAndLocation(layoutItemIds);
    groupItem.groupItemConfigData.width = size.width;
    groupItem.groupItemConfigData.height = size.height;
    groupItem.groupItemConfigData.left = size.left;
    groupItem.groupItemConfigData.top = size.top;
    store.commit('designer/addLayoutGroupItem', groupItem);
  }
}

const layoutItemShow = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemDisplay', {id: id, display: 'block'})
  });
};

const layoutItemLock = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemDraggableEnabled', {id: id, draggableEnabled: false})
  });
};

const layoutItemUnLock = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemDraggableEnabled', {id: id, draggableEnabled: true})
  });
};

const layoutItemReverseLock = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemDraggableEnabledReverse', {id: id})
  });
}

/**
 * @param layoutItemIds 布局块ID数组
 * @param showConfirm 是否显示确认提示
 */
const layoutItemDelete = function (layoutItemIds, showConfirm = true) {
  let func = () => {
    layoutItemIds.forEach(id => {
      store.commit('designer/deleteLayoutItem', id);
      store.commit('designer/setCurrentSelectLayoutItemId', '');
      store.commit('designer/setCurrentSelectLayoutItemIds', []);
      store.commit('designer/setRightSidebarFuncCompConfigFormName', '');
      store.commit('designer/deleteGroupItemLayoutItemId', id);
      EventBus.$emit('pn_deleteLayoutItem', id)
    });
  }
  if (showConfirm) {
    Modal.confirm({
      title: '提醒',
      content: '确认删除所选中的布局块吗？',
      onOk: () => {
        func()
      }
    });
  }else {
    func()
  }
};

const layoutItemCopy = function (layoutItemIds) {
  let newLayoutItemIds = copyLayoutItems(layoutItemIds);
  setTimeout(()=>{
    if (newLayoutItemIds.length == 1) {
      store.commit('designer/setCurrentSelectLayoutItemId', newLayoutItemIds[0])
    }
    store.commit('designer/setCurrentSelectLayoutItemIds', newLayoutItemIds)
  },200)
};

/**
 * 跨页复制布局块
 * @param layoutItemIds
 */
const layoutItemCopyToPage = function (layoutItemIds) {
  let shearPlateData = {
    layoutItems: []
  };

  layoutItemIds.forEach(id => {
    let layoutItem = store.getters['designer/getLayoutItemById'](id);
    shearPlateData.layoutItems.push(layoutItem)
  });

  localStorage.setItem('shearPlateData', JSON.stringify(shearPlateData))
  Message.success('已将选中布局块复制至剪切板')
}

/**
 * 设置布局块是否静止不动（响应式栅格布局中使用）
 * @param layoutItemIds
 */
const layoutItemNotStatic = function (layoutItemIds) {
  layoutItemIds.forEach(id => {
    store.commit('designer/setLayoutItemIsStatic', {id: id})
  });
}

/**
 * 粘贴跨页复制组件剪切板数据
 * @param retainLocation 是否保留位置信息
 */
const pasteShearPlateData = function (retainLocation) {
  if (localStorage.getItem('shearPlateData')) {

    let shearPlateData = JSON.parse(localStorage.getItem('shearPlateData'));

    let layoutItemLeft = -10, layoutItemTop = -10;
    shearPlateData.layoutItems.forEach(layoutItem => {
      let newLayoutItemConfigData = PnUtil.deepClone(layoutItem.layoutItemConfigData);
      if (!retainLocation) {
        newLayoutItemConfigData.left = layoutItemLeft += 20;
        newLayoutItemConfigData.top = layoutItemTop += 20;
      }

      let newLayoutItem = {
        id: PnUtil.uuid(),
        name: layoutItem.name,
        aliasName: layoutItem.aliasName,
        layoutItemConfigData: newLayoutItemConfigData,
        component: {
          id: '',
          name: '',
          compConfigData: {}
        }
      };
      if(layoutItem.component.id) {
        let newComponent = PnUtil.deepClone(layoutItem.component);
        newComponent.id = PnUtil.uuid();
        if (newComponent.compConfigData.interaction_stream) {
          newComponent.compConfigData.interaction_stream.forEach(streamItem => {
            streamItem.interaction_sender = false;
            streamItem.interaction_fieldsMap.forEach(fm => {
              fm.bindingVariateName = ''
            })
          })
        }
        newLayoutItem.component = newComponent
      }
      store.commit('designer/addLayoutItem', newLayoutItem);
    })

  }else {
    Message.warning('剪切板无任何数据')
  }
}

/**
 * 方向键移动组项
 * @param direction
 * @param currentSelectGroupItemId
 * @param currentSelectGroupItemIds
 * @param layout
 * @param currentSelectGroupItemLocation
 * @returns {*}
 */
const directionKeyMoveGroupItem = function (
  direction,
  currentSelectGroupItemId,
  currentSelectGroupItemIds,
  layout,
  currentSelectGroupItemLocation) {
  let move = (groupItem) => {
    if (groupItem) {
      let layoutItemIds = groupItem.layoutItemIds;

      if (direction == 'left') {
        store.commit('designer/setGroupItemLeftAndTopOffset', {
          id: groupItem.id,
          direction: 'left',
          offset: -layout.layoutConfigData.dragPixel
        });
        layoutItemIds.forEach(layoutItemId => {
          store.commit('designer/setLayoutItemLeftAndTopOffset', {
            id: layoutItemId,
            direction: 'left',
            offset: -layout.layoutConfigData.dragPixel
          });
        });
        // 下面这段代码是修复在用方向键移动组之后，再双击组会出现组内元素位置偏移的BUG
        if (currentSelectGroupItemLocation) {
          currentSelectGroupItemLocation[groupItem.id].left -= layout.layoutConfigData.dragPixel
        }
      } else if (direction == 'top') {
        store.commit('designer/setGroupItemLeftAndTopOffset', {
          id: groupItem.id,
          direction: 'top',
          offset: -layout.layoutConfigData.dragPixel
        });
        layoutItemIds.forEach(layoutItemId => {
          store.commit('designer/setLayoutItemLeftAndTopOffset', {
            id: layoutItemId,
            direction: 'top',
            offset: -layout.layoutConfigData.dragPixel
          });
        });
        // 下面这段代码是修复在用方向键移动组之后，再双击组会出现组内元素位置偏移的BUG
        if (currentSelectGroupItemLocation) {
          currentSelectGroupItemLocation[groupItem.id].top -= layout.layoutConfigData.dragPixel
        }
      } else if (direction == 'right') {
        store.commit('designer/setGroupItemLeftAndTopOffset', {
          id: groupItem.id,
          direction: 'left',
          offset: +layout.layoutConfigData.dragPixel
        });
        layoutItemIds.forEach(layoutItemId => {
          store.commit('designer/setLayoutItemLeftAndTopOffset', {
            id: layoutItemId,
            direction: 'left',
            offset: +layout.layoutConfigData.dragPixel
          });
        });
        // 下面这段代码是修复在用方向键移动组之后，再双击组会出现组内元素位置偏移的BUG
        if (currentSelectGroupItemLocation) {
          currentSelectGroupItemLocation[groupItem.id].left += layout.layoutConfigData.dragPixel
        }
      } else if (direction == 'bottom') {
        store.commit('designer/setGroupItemLeftAndTopOffset', {
          id: groupItem.id,
          direction: 'top',
          offset: +layout.layoutConfigData.dragPixel
        });
        layoutItemIds.forEach(layoutItemId => {
          store.commit('designer/setLayoutItemLeftAndTopOffset', {
            id: layoutItemId,
            direction: 'top',
            offset: +layout.layoutConfigData.dragPixel
          });
        });
        // 下面这段代码是修复在用方向键移动组之后，再双击组会出现组内元素位置偏移的BUG
        if (currentSelectGroupItemLocation) {
          currentSelectGroupItemLocation[groupItem.id].top += layout.layoutConfigData.dragPixel
        }
      }
    }
  };

  if (currentSelectGroupItemIds.length > 0) {
    currentSelectGroupItemIds.forEach(groupItemId => {
      let groupItem = store.getters['designer/getLayoutGroupItemById'](groupItemId);
      move(groupItem)
    })
  }else {
    let groupItem = store.getters['designer/getLayoutGroupItemById'](currentSelectGroupItemId);
    move(groupItem)
  }

  return currentSelectGroupItemLocation
}

/**
 * 方向键移动布局块
 * @param direction
 * @param currentSelectLayoutItemId
 * @param currentSelectLayoutItemIds
 * @param layout
 * @param layoutGroup
 */
const directionKeyMoveLayoutItem = function (
  direction,
  currentSelectLayoutItemId,
  currentSelectLayoutItemIds,
  layout,
  layoutGroup) {
  let stayUpdateGroupItemIds = [];
  if (currentSelectLayoutItemIds.length > 0) {
    currentSelectLayoutItemIds.forEach(id => {
      let groupItemId = getLayoutItemBelongGroupItemId(id, layoutGroup);
      if (groupItemId) {
        stayUpdateGroupItemIds.push(groupItemId)
      }
    });
  }else {
    stayUpdateGroupItemIds.push(getLayoutItemBelongGroupItemId(currentSelectLayoutItemId, layoutGroup))
  }

  if (direction == 'left') {
    if(currentSelectLayoutItemIds.length > 0) {
      currentSelectLayoutItemIds.forEach((id)=>{
        store.commit('designer/setLayoutItemLeftAndTopOffset', {
          id: id,
          direction: 'left',
          offset: -layout.layoutConfigData.dragPixel
        })
      })
    }else {
      if(currentSelectLayoutItemId) {
        store.commit('designer/setLayoutItemLeftAndTopOffset', {
          id: currentSelectLayoutItemId,
          direction: 'left',
          offset: -layout.layoutConfigData.dragPixel
        })
      }
    }
  } else if (direction == 'top') {
    if(currentSelectLayoutItemIds.length > 0) {
      currentSelectLayoutItemIds.forEach((id)=>{
        store.commit('designer/setLayoutItemLeftAndTopOffset', {
          id: id,
          direction: 'top',
          offset: -layout.layoutConfigData.dragPixel
        })
      })
    }else {
      if(currentSelectLayoutItemId) {
        store.commit('designer/setLayoutItemLeftAndTopOffset',
          {
            id: currentSelectLayoutItemId,
            direction: 'top',
            offset: -layout.layoutConfigData.dragPixel
          });
      }
    }
  } else if (direction == 'right') {
    if(currentSelectLayoutItemIds.length > 0) {
      currentSelectLayoutItemIds.forEach((id)=>{
        store.commit('designer/setLayoutItemLeftAndTopOffset',
          {
            id: id,
            direction: 'left',
            offset: +layout.layoutConfigData.dragPixel
          });
      })
    }else {
      if(currentSelectLayoutItemId) {
        store.commit('designer/setLayoutItemLeftAndTopOffset',
          {
            id: currentSelectLayoutItemId,
            direction: 'left',
            offset: +layout.layoutConfigData.dragPixel
          });
      }
    }
  } else if (direction == 'bottom') {
    if(currentSelectLayoutItemIds.length > 0) {
      currentSelectLayoutItemIds.forEach((id)=>{
        store.commit('designer/setLayoutItemLeftAndTopOffset',
          {
            id: id,
            direction: 'top',
            offset: +layout.layoutConfigData.dragPixel
          });
      })
    }else {
      if(currentSelectLayoutItemId) {
        store.commit('designer/setLayoutItemLeftAndTopOffset',
          {
            id: currentSelectLayoutItemId,
            direction: 'top',
            offset: +layout.layoutConfigData.dragPixel
          });
      }
    }
  }

  stayUpdateGroupItemIds.forEach(groupItemId => {
    updateGroupItemStoreSize(groupItemId);
  })
}

/**
 * backspace键删除布局块或组
 * @param currentSelectLayoutItemId
 * @param currentSelectLayoutItemIds
 * @param currentSelectGroupItemId
 * @param currentSelectGroupItemIds
 */
const backspaceDeleteLayoutOrGroupItem = function (
  currentSelectLayoutItemId,
  currentSelectLayoutItemIds,
  currentSelectGroupItemId,
  currentSelectGroupItemIds) {
  let arr1 = [];
  if (currentSelectLayoutItemId) {
    arr1.push(currentSelectLayoutItemId)
  }
  let arr2 = [];
  if (currentSelectGroupItemId) {
    arr2.push(currentSelectGroupItemId)
  }
  let newLayoutItemIds = _.union(arr1, currentSelectLayoutItemIds)
  let newGroupItemIds = _.union(arr2, currentSelectGroupItemIds)
  if (newLayoutItemIds.length > 0) {
    layoutItemDelete(newLayoutItemIds, false)
  }
  if (newGroupItemIds.length > 0) {
    groupItemDelete(newGroupItemIds, false)
  }
}

/**
 * 保存更新当前编辑页面
 * @param pageMetadata
 */
const saveCurrentEditPage = function (pageMetadata) {
  let page = Object.assign({}, pageMetadata);
  page.layout = JSON.stringify(page.layout);
  page.theme_json = JSON.stringify(page.theme_json);
  PnApi.PageApi.updatePage(page).then(result => {
    if(result.data.success) {
      // 更新预览数据
      localStorage.setItem('previewPageMetadata', JSON.stringify(pageMetadata));
      store.commit('designer/setPageCreateDate', result.data.payload)
      Message.success(result.data.message)
    }
  })
}
/********************************布局块与组右键菜单快捷操作封装 end ********************************/

/**
 * 获取目标布局块ID所属组的组ID
 * @param layoutItemId
 * @param layoutGroup
 */
const getLayoutItemBelongGroupItemId = function (layoutItemId, layoutGroup) {
  let belongGroupItemId = '';
  for (let i=0; i<layoutGroup.length; i++) {
    if (layoutGroup[i].layoutItemIds.indexOf(layoutItemId) > -1) {
      belongGroupItemId = layoutGroup[i].id
    }
  }
  return belongGroupItemId
};

/**
 * 清空画布
 */
const clearCanvas = function () {
  Modal.confirm({
    title: '提醒',
    content: '确认清空画布内容吗？',
    onOk: () => {
      store.commit('designer/resetDesigner')
    }
  });
}

/**
 * 初始化画布缩放比例
 * @param pageWidth
 */
const initDesignerZoomValue = function (pageWidth, defaultValue) {
  if (defaultValue) {
    store.commit('designer/setZoomValue', 1)
    return
  }
  let mainContainerWidth = $('#mainContainer').width() - 90;
  if (mainContainerWidth < pageWidth) {
    store.commit('designer/setZoomValue', Number((mainContainerWidth / pageWidth).toFixed(2)))
  }else {
    store.commit('designer/setZoomValue', 1)
  }
}

/**
 * 加载可更新的组件信息
 * @param _layoutItems
 * @returns {[]}
 */
const loadRenewableComps = function (_layoutItems) {
  let renewableComps = [];
  let layoutItems = PnUtil.deepClone(_layoutItems);
  if (layoutItems.length > 0) {
    layoutItems.forEach(layoutItem => {
      if (layoutItem.component.id && layoutItem.component.version) {
        let baseAttr = PnUtil.getCompBaseAttr(layoutItem.component.name);
        if (layoutItem.component.version != baseAttr.version) {
          renewableComps.push({
            compName: layoutItem.component.name,
            compAliasName: JSON.parse(localStorage.getItem('allCompinfoObj'))[layoutItem.component.name].alias_name,
            currentVersion: layoutItem.component.version,
            latestVersion: baseAttr.version
          })
        }
      }
    })
  }
  return renewableComps
}

/**
 * 计算生成右键菜单的位置信息
 * @param _mouseX 鼠标在浏览器屏幕的横坐标
 * @param _mouseY 鼠标在浏览器屏幕的纵坐标
 * @param _menuClientHeight 菜单容器的高度
 */
const calculateContextmenuPosition = function (_mouseX, _mouseY, _menuClientHeight) {
  let position = {
    left: Math.ceil(_mouseX),
    top: 0
  }
  let clientHeight = document.body.clientHeight;
  if (clientHeight - _mouseY > (_menuClientHeight + 10)) {
    position.top = Math.ceil(_mouseY)
  }else if (clientHeight - _mouseY < (_menuClientHeight + 10)) {
    position.top = Math.ceil(_mouseY - _menuClientHeight)
  }
  return position
}

/**
 * 获取页面源数据中所有交互变量名
 * @param layoutItems
 * @returns {[]}
 */
const getPageAllBindingVariateNames = function (layoutItems) {
  let allBindingVariateNames = [];
  for (let i=0; i<layoutItems.length; i++) {
    if (layoutItems[i].component.id) {
      if (layoutItems[i].component.compConfigData.interaction_stream) {
        layoutItems[i].component.compConfigData.interaction_stream.forEach(streamItem => {
          if (streamItem.interaction_fieldsMap) {
            streamItem.interaction_fieldsMap.forEach(fm => {
              if (fm.bindingVariateName) {
                allBindingVariateNames.push(fm.bindingVariateName)
              }
            })
          }
        })
      }
    }
  }
  return allBindingVariateNames
}

/**
 * 切换单独显示图层
 * @param formType 'layoutItems','groupItems'
 * @param targetIdList 被单独显示的目标ID集合
 * @param operate 'enter','cancel','cancelAll'
 */
const toggleAlongShowLayout = function (formType, targetIdList, operate) {

  let groupItems = store.getters['designer/getLayoutGroup']

  switch (operate) {
    case 'enter':
      if (formType == 'layoutItems') {
        let newTargetIdList = _.union(store.state.designer.alongShowTargetIdList, targetIdList)
        store.commit('designer/setAlongShowTargetIdList', newTargetIdList)
      }else if (formType == 'groupItems') {
        let newTargetIdList = _.union(store.state.designer.alongShowTargetIdList, targetIdList)
        groupItems.forEach(groupItem => {
          if (targetIdList.indexOf(groupItem.id) > -1) {
            let layoutItemIds = groupItem.layoutItemIds
            newTargetIdList = _.union(newTargetIdList, layoutItemIds)
          }
        })
        store.commit('designer/setAlongShowTargetIdList', newTargetIdList)
      }
      break
    case 'cancel':
      if (formType == 'layoutItems') {
        let newTargetIdList = _.remove(store.state.designer.alongShowTargetIdList, function (o) {
          return targetIdList.indexOf(o) < 0
        })
        store.commit('designer/setAlongShowTargetIdList', newTargetIdList)
      }else if (formType == 'groupItems') {
        let newAlongShowTargetIdList = _.remove(store.state.designer.alongShowTargetIdList, function (o) {
          return targetIdList.indexOf(o) < 0
        })
        groupItems.forEach(groupItem => {
          if (targetIdList.indexOf(groupItem.id) > -1) {
            let layoutItemIds = groupItem.layoutItemIds
            newAlongShowTargetIdList = _.remove(newAlongShowTargetIdList, function (o) {
              return layoutItemIds.indexOf(o) < 0
            })
          }
        })
        store.commit('designer/setAlongShowTargetIdList', newAlongShowTargetIdList)
      }
      break
    case 'cancelAll':
      store.commit('designer/resetAlongShowTargetIdList')
      Message.success('成功关闭所有独显图层状态')
      break
  }
}

/**
 * 复制组件配置
 * @param layoutItemId
 */
const copyComponentConfigData = function (layoutItemId) {
  Modal.confirm({
    title: '复制关联组件的配置',
    content: '组件的所有配置（不包括布局块的配置）都会被复制进浏览器本地存储等待粘贴至同类型目标组件，包括数据源以及交互的配置！配置复制操作只能针对单个组件进复制，配置粘贴可粘贴于多个同类型组件中。',
    onOk: () => {
      LoadingBar.start()
      let promise = new Promise((resolve, reject) => {
        let layoutItem = store.getters['designer/getLayoutItemById'](layoutItemId);
        let copyAndPasteCompConfigData = {
          componentName: null,
          compConfigData: null,
        }
        if (layoutItem.component.id) {
          copyAndPasteCompConfigData.componentName = layoutItem.component.name
          copyAndPasteCompConfigData.compConfigData = layoutItem.component.compConfigData
          localStorage.setItem('copyAndPasteCompConfigData', JSON.stringify(copyAndPasteCompConfigData))
          resolve('配置复制成功')
        }else {
          reject('所选布局块未绑定组件，无法进行组件配置复制操作')
        }
      })
      promise.then((successMessage)=>{
        Message.success(successMessage)
        LoadingBar.finish()
      }).catch(errorMessage => {
        Message.warning({
          content: errorMessage,
          duration: 5
        })
        LoadingBar.error()
      })
    }
  });
}

/**
 * 粘贴组件配置
 * @param layoutItemIds
 */
const pasteComponentConfigData = function (layoutItemIds) {
  Modal.confirm({
    title: '粘贴配置至关联组件',
    content: '确定将剪切板中复制的组件配置粘贴至当前所选组件中吗？',
    onOk: () => {
      let promise = new Promise((resolve, reject) => {
        LoadingBar.start()
        let copyAndPasteCompConfigData = JSON.parse(localStorage.getItem('copyAndPasteCompConfigData'))
        if (!copyAndPasteCompConfigData) {
          reject('剪切板中无可粘贴的组件配置')
        }
        let layoutItemArr = []
        layoutItemIds.forEach(layoutItemId => {
          layoutItemArr.push(store.getters['designer/getLayoutItemById'](layoutItemId))
        })
        let flag = true
        for (let i=0; i<layoutItemArr.length; i++) {
          if (!layoutItemArr[i].component.id) {
            flag = false
            reject('所选布局块中存在未绑定组件的项')
          }
          if (copyAndPasteCompConfigData.componentName != layoutItemArr[i].component.name) {
            flag = false
            reject('所选布局块关联的组件中有与剪切板中被复制的组件不是同一类型组件的项')
          }
        }
        if (flag) {
          let layoutItems = store.getters['designer/getLayoutItems']
          layoutItemArr.forEach(layoutItem => {
            layoutItem.component.compConfigData = copyAndPasteCompConfigData.compConfigData
          })
          layoutItemArr.forEach(layoutItem1 => {
            layoutItems.forEach(layoutItem2 => {
              if (layoutItem1.id == layoutItem2.id) {
                layoutItem2.component.compConfigData = layoutItem1.component.compConfigData
              }
            })
          })
          store.commit('designer/setLayoutItems', layoutItems)
        }
        resolve('组件配置粘贴成功')
      })
      promise.then((result) => {
        Message.success(result)
        LoadingBar.finish()
      }).catch(error => {
        Message.warning({
          content: error,
          duration: 5
        })
        LoadingBar.error()
      })
    }
  });
}

/**
 * 拆分布局块
 * @param type 拆分类型
 * @param layoutItemId 目标布局块ID
 * @param splitNum 拆分数
 * @param marginNum 间隔
 */
const splitLayoutItem = function (type, layoutItemId, splitNum = 1, marginNum = 0) {
  let createNewLayoutItem = function (layoutItem) {
    let newLayoutItem = PnUtil.deepClone(layoutItem)
    newLayoutItem.id = PnUtil.uuid()
    newLayoutItem.aliasName = ''
    newLayoutItem.layoutItemConfigData.className = ''
    newLayoutItem.component = {id: '',name: '',compConfigData: {}}
    return newLayoutItem
  }
  let promise = new Promise((resolve, reject) => {
    let layoutItem = store.getters['designer/getLayoutItemById'](layoutItemId);
    let layoutItemBelongGroupId = getLayoutItemBelongGroupItemId(layoutItemId, store.getters['designer/getLayoutGroup'])
    let newLayoutItems = [] // 存储拆分之后的布局块集合
    // 横向拆分
    if (type === 'h') {
      let newWidth = Math.floor((layoutItem.layoutItemConfigData.width-(marginNum*(splitNum-1)))/splitNum)
      let lastLeft = layoutItem.layoutItemConfigData.left
      for (let i=0; i<splitNum; i++) {
        if (i == 0) {
          store.commit('designer/setLayoutItemWhlt', {
            id: layoutItemId,
            width: newWidth,
            height: layoutItem.layoutItemConfigData.height,
            left: layoutItem.layoutItemConfigData.left,
            top: layoutItem.layoutItemConfigData.top
          })
        }else {
          let newLayoutItem = createNewLayoutItem(layoutItem)
          newLayoutItem.layoutItemConfigData.width = newWidth
          newLayoutItem.layoutItemConfigData.height = layoutItem.layoutItemConfigData.height
          newLayoutItem.layoutItemConfigData.left = lastLeft
          newLayoutItem.layoutItemConfigData.top = layoutItem.layoutItemConfigData.top
          newLayoutItems.push(newLayoutItem)
        }
        lastLeft += newWidth + marginNum
      }
    }
    // 纵向拆分
    else if (type === 'v') {
      let newHeight = Math.floor((layoutItem.layoutItemConfigData.height-(marginNum*(splitNum-1)))/splitNum)
      let lastTop = layoutItem.layoutItemConfigData.top
      for (let i=0; i<splitNum; i++) {
        if (i == 0) {
          store.commit('designer/setLayoutItemWhlt', {
            id: layoutItemId,
            width: layoutItem.layoutItemConfigData.width,
            height: newHeight,
            left: layoutItem.layoutItemConfigData.left,
            top: layoutItem.layoutItemConfigData.top
          })
        }else {
          let newLayoutItem = createNewLayoutItem(layoutItem)
          newLayoutItem.layoutItemConfigData.width = layoutItem.layoutItemConfigData.width
          newLayoutItem.layoutItemConfigData.height = newHeight
          newLayoutItem.layoutItemConfigData.left = layoutItem.layoutItemConfigData.left
          newLayoutItem.layoutItemConfigData.top = lastTop
          newLayoutItems.push(newLayoutItem)
        }
        lastTop += newHeight + marginNum
      }
    }
    newLayoutItems.forEach(layoutItem => {
      store.commit('designer/addLayoutItem', layoutItem)
    })
    store.commit('designer/clearAllSelected')

    // 如果当前被拆分的布局块是被成组的
    if (layoutItemBelongGroupId) {
      store.commit('designer/addLayoutItemsToGroupItem', {
        targetGroupItemId: layoutItemBelongGroupId,
        newLayoutItemIds: newLayoutItems.map((o)=>{return o.id})
      })
      calculateGroupItemSizeAndLocation(_.concat([layoutItemId], newLayoutItems.map((o)=>{return o.id})))
    }
    resolve('拆分成功')
  })
  return promise
}

/**
 * 切换独立组件编辑模式
 * @param isOpen 打开关闭状态：true or false
 * @param targetPageId 目标页面ID
 * @param layoutItemIds 目标布局块ID，可多个
 * @param groupItemIds 目标组ID，可多个
 */
const toggleAlongCompEditModel = function (isOpen, targetPageId = '', layoutItemIds = [], groupItemIds = []) {
  if (isOpen) {
    // 获取当前页面布局中的所有组和布局块
    let layoutGroup = store.getters["designer/getLayoutGroup"]
    let layoutItems = store.getters["designer/getLayoutItems"]

    let targetLayoutItems = []
    let targetGroupItems = []

    let promise = new Promise((resolve, reject) => {
      Spin.show()
      if (groupItemIds.length == 0) { // 如果groupItemIds为空数组，那么目标是布局块
        for (let i=0; i<layoutItemIds.length; i++) {
          let belongGroupItemId = getLayoutItemBelongGroupItemId(layoutItemIds[i], layoutGroup)
          if (belongGroupItemId) {
            let targetGroupItem = store.getters["designer/getGroupItemById"](belongGroupItemId)
            targetGroupItems.push(targetGroupItem)
            for (let layoutItemId of targetGroupItem.layoutItemIds) {
              let targetLayoutItem = store.getters["designer/getLayoutItemById"](layoutItemId)
              targetLayoutItems.push(targetLayoutItem)
            }
            layoutItemIds.splice(i, 1)
            i--
          }else {
            let targetLayoutItem = store.getters["designer/getLayoutItemById"](layoutItemIds[i])
            targetLayoutItems.push(targetLayoutItem)
          }
        }
        resolve()
      }
      if (layoutItemIds.length == 0) {// 如果layoutItemIds为空数组，那么目标是组
        for (let i=0; i<groupItemIds.length; i++) {
          let targetGroupItem = store.getters["designer/getGroupItemById"](groupItemIds[i])
          targetGroupItems.push(targetGroupItem)
          for (let layoutItemId of targetGroupItem.layoutItemIds) {
            let targetLayoutItem = store.getters["designer/getLayoutItemById"](layoutItemId)
            targetLayoutItems.push(targetLayoutItem)
          }
        }
        resolve()
      }
    })
    promise.then(()=>{
      let alongCompEditCacheData = [{
        targetPageId: targetPageId,
        targetLayoutItems: targetLayoutItems,
        targetGroupItems: targetGroupItems,
        layout: {
          layoutGroup: layoutGroup,
          layoutItems: layoutItems
        }
      }]

      store.commit('designer/setAlongCompEditCacheData', alongCompEditCacheData)
      store.commit('designer/setLayoutItems', targetLayoutItems)
      store.commit('designer/setLayoutGroup', targetGroupItems)
      store.commit('designer/setIsAlongCompEditModel', true)
      Spin.hide()
    })
  }else {
    let currentLayoutGroup = store.getters["designer/getLayoutGroup"]
    let currentLayoutItems = store.getters["designer/getLayoutItems"]
    let alongCompEditCacheData = store.state.designer.alongCompEditCacheData
    let cacheLayoutGroup = alongCompEditCacheData[0].layout.layoutGroup
    let cacheLayoutItems = alongCompEditCacheData[0].layout.layoutItems
    let promise = new Promise((resolve, reject) => {
      Spin.show()
      for (let i=0; i<cacheLayoutItems.length; i++) {
        for (let j=0; j<currentLayoutItems.length; j++) {
          if (cacheLayoutItems[i].id == currentLayoutItems[j].id) {
            cacheLayoutItems[i] = currentLayoutItems[j]
          }
        }
      }
      for (let i=0; i<cacheLayoutGroup.length; i++) {
        for (let j=0; j<currentLayoutGroup.length; j++) {
          if (cacheLayoutGroup[i].id == currentLayoutGroup[j].id) {
            cacheLayoutGroup[i] = currentLayoutGroup[j]
          }
        }
      }
      resolve()
    })
    promise.then(() => {
      store.commit('designer/setAlongCompEditCacheData', [])
      store.commit('designer/setLayoutGroup', cacheLayoutGroup)
      store.commit('designer/setLayoutItems', cacheLayoutItems)
      store.commit('designer/setIsAlongCompEditModel', false)
      Spin.hide()
    })
  }
}

export default {
  buildInitPageMetadata,
  buildAbsoluteLayoutConfigData,
  buildAbsoluteLayoutItem,
  buildAbsoluteGroupItem,

  calculateGroupItemSizeAndLocation,
  updateGroupItemStoreSize,

  groupItemSetTop,
  groupItemSetDown,
  groupItemHide,
  groupItemReverseHideOrShow,
  groupItemShow,
  groupItemLock,
  groupItemUnLock,
  groupItemReverseLock,
  groupItemUndo,
  groupItemDelete,
  groupItemCopy,
  copyLayoutItems,
  layoutItemSetTop,
  layoutItemSetTopOne,
  layoutItemSetDown,
  layoutItemSetDownOne,
  layoutItemHide,
  affirmLayoutItemsByGroup,
  layoutItemCreateGroup,
  layoutItemShow,
  layoutItemLock,
  layoutItemUnLock,
  layoutItemReverseLock,
  layoutItemDelete,
  layoutItemCopy,
  layoutItemCopyToPage,
  layoutItemNotStatic,
  pasteShearPlateData,

  directionKeyMoveGroupItem,
  directionKeyMoveLayoutItem,
  backspaceDeleteLayoutOrGroupItem,
  saveCurrentEditPage,

  getLayoutItemBelongGroupItemId,

  clearCanvas,
  initDesignerZoomValue,

  loadRenewableComps,
  calculateContextmenuPosition,

  getPageAllBindingVariateNames,
  toggleAlongShowLayout,

  copyComponentConfigData,
  pasteComponentConfigData,

  splitLayoutItem,

  toggleAlongCompEditModel
}
